package com.hsd.whb.service.impl;

import com.hsd.whb.converter.DeviceConverter;
import com.hsd.whb.entity.Device;
import com.hsd.whb.entity.Manager;
import com.hsd.whb.enums.DeviceStatusEnum;
import com.hsd.whb.enums.ResultEnum;
import com.hsd.whb.exception.HwbException;
import com.hsd.whb.pojo.output.DeviceVO;
import com.hsd.whb.pojo.query.QueryDevice;
import com.hsd.whb.repository.DeviceRepository;
import com.hsd.whb.repository.ManagerRepository;
import com.hsd.whb.service.DeviceService;
import com.hsd.whb.utils.BeanUtil;
import com.wangjiacai.hqlQuery.service.impl.BaseServiceImpl;
import com.wangjiacai.hqlQuery.util.HqlUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service
public class DeviceServiceImpl extends BaseServiceImpl implements DeviceService {

    @Autowired
    private DeviceRepository deviceRepository;

    @Autowired
    private ManagerRepository managerRepository;

    @Override
    public Device updateDevice(Device device) {
        Device target = deviceRepository.getOne(device.getId());
        BeanUtil.copyPropertiesIgnoreNull(device, target);
        return deviceRepository.save(target);
    }

    @Override
    public Device bindingDevice(Device device, String managerName) {
        validBindingDevice(device);
        Manager manager = managerRepository.findByUsername(managerName);
        device = deviceRepository.findByAccessKey(device.getAccessKey());
        device.setManagerId(manager.getId());
        return deviceRepository.save(device);
    }

    @Override
    public Device findDeviceById(Integer id) {
        return deviceRepository.getOne(id);
    }

    @Override
    public Device findDeviceByAccessKey(String accessKey) {
        return deviceRepository.findByAccessKey(accessKey);
    }

    @Override
    public void deleteDeviceById(Integer id) {
        Device device = deviceRepository.getOne(id);
        device.setDeleted(1);
        deviceRepository.save(device);
    }

    @Override
    public List<DeviceVO> findDeviceByManagerId(Integer managerId) {
        List<Device> list = deviceRepository.findByManagerIdAndDeleted(managerId, 0);
        return DeviceConverter.convertToDeviceVOList(list);
    }

    @Override
    public long findDeviceListTotalPages(String username, Device device) {
        Manager manager = managerRepository.findByUsername(username);
        device.setManagerId(manager.getId());
        device.setDeleted(0);
        return this.count(HqlUtil.getCountHql(device), device);
    }


    @Override
    public List<Device> findDeviceList(Pageable pageable, String username, Device device) {
        Manager manager = managerRepository.findByUsername(username);
        device.setManagerId(manager.getId());
        device.setDeleted(0);
        return this.find(HqlUtil.getQueryHql(device), device, pageable,Device.class);
    }

    @Override
    public long findAllDeviceListTotalPages(QueryDevice queryDevice) {
        if (!StringUtils.isEmpty(queryDevice.getManagerName())) {
            List<Integer> list = managerRepository.findIdByUsernameLike(queryDevice.getManagerName());
            if (list.isEmpty()) return 0;
            queryDevice.setManagerId(list);
        }
        queryDevice.setDeleted(0);
        return this.count(HqlUtil.getCountHql(queryDevice), queryDevice);
    }


    @Override
    public List<Device> findAllDeviceList(Pageable pageable, QueryDevice queryDevice) {
        if (!StringUtils.isEmpty(queryDevice.getManagerName())) {
            List<Integer> list = managerRepository.findIdByUsernameLike(queryDevice.getManagerName());
            if (list.isEmpty()) return new ArrayList<>();
            queryDevice.setManagerId(list);
        }
        queryDevice.setDeleted(0);
        return this.find(HqlUtil.getQueryHql(queryDevice), queryDevice, pageable,Device.class);
    }

    private void validAddDevice(Device device) {
        if (deviceRepository.findByAccessKey(device.getAccessKey()) != null) {
            throw new HwbException(ResultEnum.ACCESS_KEY_EXIST);
        }
    }

    private void validBindingDevice(Device device) {
        device = deviceRepository.findByAccessKey(device.getAccessKey());
        if (deviceRepository.findByAccessKey(device.getAccessKey()) == null) {
            throw new HwbException(ResultEnum.DEVICE_NOT_EXIST);
        }
        if (device.getManagerId() != null) {
            throw new HwbException(ResultEnum.DEVICE_EXIST_BINDING);
        }
    }
}
